PIC−パソコン間シリアル通信 PIC送信テスト(その2)


PICからパソコンへメッセージを送ってみよう!

<項目>シリアル送信動作の確認プログラム(2)
図1にシリアル送信のフローチャートを示します。
プログラムの解説については、「プログラムの説明(2)」の項をご参照ください。

シリアル送信プログラム(2)フローチャート
図1.シリアル送信プログラム(2)
フローチャート

(注)以下に示すプログラムには、ホームページ画面作成の都合上、空白として全角文字のスペースなどが挿入されています。したがって、下記プログラムリストをそのままコピーしてMPLABのソースファイルとされた場合には、エラーとなることがあります。

→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
   <ダウンロードする>ファイル名:「tx_2.asm」 サイズ4.87kバイト

→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
   <ダウンロードする>ファイル名:「tx_2.hex」 サイズ615バイト

プログラムリスト中、青字となっている行が、前ページのシリアル送信動作チェックプログラム(1)で変更された部分です。

;***********************************************************
; シリアル送信動作チェックプログラム(2)
; 送信状態に入ると、確認のため PORTB の LED が1秒間点灯
; LED が消灯すると同時にメッセージを PIC から送信
; 非同期式通信モード
; ボーレート 9600bps(高速モード)
; 8ビット・ノンパリティ
; 割り込みは使用しない
;***********************************************************
    LIST   P=PIC16F877
    INCLUDE  P16F877.INC
;(1)プロセッサの種別指定
;(2)インクルードファイルの指定
;***********************************************************
; 変数定義とレジスタ割付
;***********************************************************
COUNT  EQU 20H
COUNT1 EQU 21H
COUNT2 EQU 22H
COUNT3 EQU 23H
COUNT4 EQU 24H
TEMP  EQU 25H
POINT  EQU 26H


   ORG  0
;(3)ループカウンタ
;   ループカウンタ1
;   ループカウンタ2
;   ループカウンタ3
;   ループカウンタ4
;(3')ワークエリア
;   テーブルポインタ


;(4)プログラムの開始番地の指定
;***********************************************************
; 送受信モードの初期化
; (注)バンクの位置に注意
;***********************************************************
    BSF    STATUS,RP0
    MOVLW   B'10111111'
    MOVWF   TRISC
    CLRF   TRISB
    MOVLW   B'00100100'
    MOVWF   TXSTA
    MOVLW   81H
    MOVWF   SPBRG
    BCF    STATUS,RP0
    MOVLW   B'10010000'
    MOVWF   RCSTA
;(5)Bank 1 へ切替
;(6)RC7/RX(入力),RC6/TX(出力)
;(7)PORTC の設定
;(8)PORTB 全ポートを出力に設定
;(9)8BIT,送信許可,非同期,高速
;   TXSTA レジスタの設定
;(10)ボーレート 9600bps (20MHz:高速設定時)
;   SPBRG レジスタの設定
;(11)Bank 0 へ戻す
;(12)シリアル,8BIT,継続受信許可
;   RCSTA レジスタの設定
;***********************************************************
; メインプログラム
;***********************************************************
    MOVLW   B'11111111'
    MOVWF   PORTB
    CALL   TIME1S
    MOVLW   B'00000000'
    MOVWF   PORTB
TEXT
    CLRF   POINT
LPTEX
    MOVF   POINT,W
    CALL   TABLE
    ADDLW   0
    BTFSC   STATUS,Z
    GOTO   END_LP
    CALL   TX
    INCF   POINT,F
    GOTO   LPTEX

END_LP
    GOTO   END_LP
;(13)11111111 を Wreg にロードする
;   PORTBへWregのデータを出力(LEDの全点灯)
;(14)1秒のウエイトを入れる
;(15)00000000 を Wreg にロードする
;   PORTBへWregのデータを出力(LEDの消灯)
;
;(30)テーブルポインタのリセット
;
;(31)テーブルポインタの値をWregへロードする(OFFSET)
;(32)テキストデータの読み込みサブルーチンへ
;(33)Wregレジスタに0を加算する
;(34)演算結果がゼロかチェック(テキストデータは「0」?)
;(35)テキストデータが終了のとき END_LPへジャンプ
;(36)テキストデータを出力するため送信サブルーチンへ
;(37)テーブルポインタ +1
;(38)LPTEX のラベルへ戻り繰り返す

;
;(21)送信終了
;***********************************************************
; テキストデータテーブル
;***********************************************************
TABLE
    ADDWF   PCL,F
;
;(39)PC+OFFSET
    DT    "SPECTRUM 電子工作のホームページ",0,0,0,0,0,0,0,0
;(40)TABLEの定義(PC+OFFSET相当のデータを持って戻る)
;***********************************************************
; 送信サブルーチン
; 送信可能かのチェックは送信レジスタが空であることで確認
; (つまり、TRMT=1で可能と判定する)
; (注)TXATAのあるバンクに注意
;***********************************************************
TX
    MOVWF   TEMP

    BSF    STATUS,RP0
LPTX
    BTFSS   TXSTA,TRMT
    GOTO   LPTX
    BCF    STATUS,RP0
    
MOVF   TEMP,W
    MOVWF   TXREG
    
RETURN
;
;(16')送信するデータを変数(TEMP)に格納

;(16)Bank 1 へ切替
;
;(17)送信可能であるかチェック(1:可能, 0:禁止)
;   禁止であれば LPTX のラベル間を繰り返す
;(18)Bank 0 へ戻す
;(19')変数(TEMP)に格納していた送信データをWregにロード
;(20)送信データはTXREGレジスタを通してシリアル出力される
;(21')メインルーチンへ戻る
;***********************************************************
;遅延サブルーチン
;***********************************************************
;100μs遅延サブルーチン(20MHzクロック時)
;・・・・・別記プログラムリスト参照・・・・・
;
;10ms遅延サブルーチン(20MHzクロック時)
;・・・・・別記プログラムリスト参照・・・・・
;
;1s遅延サブルーチン(20MHzクロック時)
;・・・・・別記プログラムリスト参照・・・・・

    END
 

【プログラムの説明(2)】ここがポイント
このプログラムについて、解説を加えておきましょう。ただし、前ページで解説したプログラム(1)の説明と重複する部分は省略します。ここではプログラムリスト中、青字となっている行を解説します。その他の行はプログラムの説明(1)をご覧ください。プログラム中のコメントの番号ですが、プログラムの説明(1)と同等な箇所には、そのままの番号を使っています。また、コメントの番号の順序関係が前後しておりますが、特に意味はありません。


(3’)変数定義とレジスタ割付
TEMPは、送信する文字を一時格納しておく変数
POINTは、送信文字列(テーブル)の位置を示すテーブルポインタ変数
それぞれ、レジスタファイルアドレスに割り付けます。

(30)テーブルポインタのリセット
送信文字列(テープル)の位置を示すテーブルポインタを「0」にします。
(先頭の文字位置に設定)

(31)テーブルポインタの値をWregへロードする(OFFSET)
送信文字列(テープル)の位置を示すテーブルポインタをWregにロードします。
このときの数値が、プログラムカウンタのオフセットになります。

(32)テキストデータの読み込みサブルーチンへ
送信文字列が書かれたテキストデータの読み込みサブルーチンへジャンプします。

(39)PC+OFFSETここがポイント
テキストデータテーブルのサブルーチンに来ると、プログラムカウンタに、Wregの値(オフセット)が加算されます。その加算結果をプログラムカウンタとしますので、そのアドレスで指定された文字データを示すようになります。

ADDWF   PCL,F ;プログラムカウンタに、Wregの値(オフセット)を加算し、
             その加算結果をプログラムカウンタする。

(40)TABLEの定義(PC+OFFSET相当のデータを持って戻る)
DTは、テーブルデータをプログラムメモリ内に定義する疑似命令です。また、データをWregにセットしてサブルーチンから復帰します。すなわち、PC+OFFSET相当の文字データを持って戻ります。

(33)Wregレジスタに0を加算するここがポイント
Wregレジスタには、PC+OFFSET相当の文字データ(送信すべき文字)が入っています。ここで文字データに数値「0」を加算します。加算値が「0」ですので、当然加算前後で文字データそのものには変化はありません。ところで、(40)番のTABLEで定義された文字列の最後の方に0を並べておきました。

"SPECTRUM 電子工作のホームページ",0,0,0,0,0,0,0,0 ←ここの部分(8ビット分で数値の「0」を示す)

先頭文字「S」から順次文字データが読み込まれますが、数値「0」を文字列の最後を判断するのに使っています。受け取るデータが数値「0」であれば、加算結果が「0」になりますから、ゼロステータスが「1」に変化します。

(注)ここでの「0」は数値データの「0」で、文字コードの「0」ではありません。
ちなみに文字コードの「0」は、B’00110000’の30Hになります。

(34)演算結果がゼロかチェック(テキストデータは「0」?)
ゼロステータスが「0」のまま(文字データ有)であったならば、次の命令をスキップします。ゼロステータスが「1」(文字データ無)であったならば、次の命令を実行します。

(35)テキストデータが終了を示す「0」のとき END_LPへジャンプ
先の判断分岐命令で、ゼロステータスが「1」(文字データ無)であったならば、この命令が実行されます。すなわち、送信終了のループ(END_LP)にジャンプします。

(36)テキストデータを出力するため送信サブルーチンへ
先の判断分岐命令で、ゼロステータスが「0」のまま(文字データ有)であったならば、この命令を実行します。すなわち、文字データを出力するための送信ルーチンへジャンプします。

(16’)送信するデータを変数(TEMP)に格納
Wregにある送信文字データを変数TEMPに格納して退避させておきます。

(16)Bank 1 へ切替
送信レジスタステータスビット(TRMT)の状態を確認するため、 TXSTAレジスタのあるBank1へ切り替えます。

(17)送信可能であるかチェック(1:可能, 0:禁止)
    禁止であれば LPTX のラベル間を繰り返す

TXSTAレジスタの送信レジスタステータスビット(TRMT)の状態をチェックします。
送信が可能であるとすると、TRMTが「1」となり、次の命令で分岐されます。
BTFSS   TXSTA,TRMT
「TXSTA」レジスタのTRMTビットが「1」だったら次の命令をスキップし、ループから抜けます。
GOTO   LPTX
ただし、送信が禁止の間は、「TXSTA」レジスタのTRMTビットが「0」のままですので、LPTXラベルへ戻ってループを繰り返します。

(18)Bank 0 へ戻す
「TXSTA」レジスタの送信レジスタステータスの内容を確認したら、Bank0に戻しておきましょう。

(19’)変数(TEMP)に格納していた送信データをWregにロード
変数TEMPに格納して退避させておいた文字をパソコン側へ送信します。

(20)TXREGレジスタを通してシリアル出力
Wregに格納してあったデータを、TXREGレジスタにロードすることで、データがシリアル出力されます。

(21’)メインルーチンへ戻る
RETURN命令でメインルーチンへ復帰します。

(37)テーブルポインタ +1
テーブルポインタの値(オフセット)を+1します。

(38)LPTEX のラベルへ戻り繰り返す
LPTEXのラベルまで戻り繰り返す。

(21)送信終了
送信が終了したら、「END_LP」ラベル間をループさせておしまい。


<項目>シリアル送信動作の確認
上記のプログラムを、PICWWで書き込んでおきます。次にAcknowrichを起動し、ボーレートを9600bpsに設定します。それでは、PIC側でリセットスイッチを押してみましょう。PortBに接続したLEDが、1秒間点灯した後に、文字列が送信され、通信ログエリアに文字が表示されます。図2にPICから文字が送信されたときの、Acknowrich表示画面を示します。プログラムの方で、”SPECTRUM 電子工作のホームページ”と設定していましたので、Acknowrichの方でもその文字が出ればOKです。

<項目>
図2.PICから文字が送信されたときの、Acknowrich表示画面





<戻る> <次ページへ>
<TOPページへ>



テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル